package jmine.tec.hydra.web.pages.requisicao;

import static jmine.tec.web.wicket.pages.form.WebFormPagesMessages.ERROR_CANNOT_FIND_ENTITY_TO_VIEW;
import images.ImageResources;

import java.io.IOException;
import java.io.Serializable;
import java.util.List;

import jmine.tec.hydra.HydraController;
import jmine.tec.hydra.api.HydraAction;
import jmine.tec.hydra.api.HydraMessage;
import jmine.tec.hydra.dao.HydraRequestDAO;
import jmine.tec.hydra.domain.HydraRequestImpl;
import jmine.tec.hydra.domain.message.HydraMessageImpl;
import jmine.tec.web.pages.HelpTextMessages;
import jmine.tec.web.wicket.pages.form.AbstractFormPage;

import org.apache.wicket.Page;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import bancosys.tec.exception.BusinessException;
import bancosys.tec.exception.MessageCreator;
import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.persist.dao.BeanNotFoundException;
import bancosys.tec.security.annotation.Secure;
import bancosys.tec.security.authorization.UrlPermission;

/**
 * Tela de consulta de detalhe das requisições feitas ao hydra.
 * 
 * @author finx
 * @created Nov 6, 2010
 */
@Secure(id = "URL_SHOW_INTEGRACAO_REQUISICAO", permissionType = UrlPermission.class)
public class ConsultaDetalheIntegracaoRequisicao extends AbstractFormPage {

    protected static final int INITIAL_WIDTH_MODAL = 750;

    protected static final int INITIAL_HEIGHT_MODAL = 150;

    private Form<HydraRequestImpl> form = null;

    @SpringBean(name = "hydraController")
    private HydraController hydraController;

    private List<HydraAction> actionsList;

    private final HydraRequestImpl hydraRequest;

    private final Page returnPage;

    /**
     * Construtor.
     * 
     * @param hydraRequestPk PK do request a ser detalhado na tela.
     * @param returnPage a pagina de retorno
     */
    public ConsultaDetalheIntegracaoRequisicao(Serializable hydraRequestPk, Page returnPage) {
        super();
        try {
            this.hydraRequest = this.getHydraRequestDAO().findByPk(hydraRequestPk);
            this.returnPage = returnPage;
            this.actionsList = this.hydraRequest.getActions();
            this.initForm();
            this.createComponents();
        } catch (BeanNotFoundException e) {
            throw new BusinessException(ERROR_CANNOT_FIND_ENTITY_TO_VIEW.create(this.getPageName(), hydraRequestPk));
        }
    }

    /**
     * Inicializa o form.
     */
    private void initForm() {
        this.form = new Form<HydraRequestImpl>("mainForm");
        this.add(new FeedbackPanel("feedback"));
        this.add(this.form);
    }

    /**
     * Cria os componentes da tela.
     */
    private void createComponents() {
        this.form.setModel(new Model<HydraRequestImpl>(this.hydraRequest));

        ListView<HydraAction> actionsListView =
                new ListView<HydraAction>("actionsList", new PropertyModel<List<HydraAction>>(this, "actionsList")) {

                    @Override
                    protected void populateItem(ListItem<HydraAction> item) {
                        HydraAction action = item.getModelObject();
                        item.add(new Label("descricao", action.getDescription()));
                        item.add(new Label("status", action.getStatus().getName()));

                        final ModalWindow modalDetalhe = new ModalWindow("modalPanelDetalheHydraAction");
                        modalDetalhe.setInitialWidth(INITIAL_WIDTH_MODAL);
                        modalDetalhe.setInitialHeight(INITIAL_HEIGHT_MODAL);
                        modalDetalhe.setContent(new ModalPanelDetalheHydraAction(modalDetalhe.getContentId(),
                                ConsultaDetalheIntegracaoRequisicao.this.hydraController, action));
                        modalDetalhe.setTitle("Detalhe Requisição");
                        item.add(modalDetalhe);

                        AjaxLink<Void> linkDetalhe = new AjaxLink<Void>("consultarDetalhe") {
                            @Override
                            public void onClick(AjaxRequestTarget target) {
                                modalDetalhe.show(target);
                            }
                        };
                        linkDetalhe.add(new Image("imgDetalheHydraAction", new ResourceReference(ImageResources.class, "magnifier.png")));
                        item.add(linkDetalhe);
                    }

                };
        actionsListView.setOutputMarkupId(true);
        this.form.add(actionsListView);
        String messageBody = this.getMessageBody(this.hydraRequest);
        TextArea<String> txtMessageBody = new TextArea<String>("messageBody", new Model<String>(messageBody));
        txtMessageBody.setConvertedInput(messageBody);
        txtMessageBody.setVisible(messageBody != null);
        this.form.add(txtMessageBody);

        this.form.add(new Link<Object>("btnVoltar") {
            @Override
            public void onClick() {
                this.setResponsePage(ConsultaDetalheIntegracaoRequisicao.this.returnPage);
            }
        });

    }

    /**
     * @return the actionsList
     */
    public List<HydraAction> getActionsList() {
        return this.actionsList;
    }

    /**
     * @param actionsList the actionsList to set
     */
    public void setActionsList(List<HydraAction> actionsList) {
        this.actionsList = actionsList;
    }

    /**
     * Obtem o corpo da mensagem da request.
     * 
     * @param request {@link HydraRequestImpl}
     * @return Corpo da mensagem.
     */
    public String getMessageBody(HydraRequestImpl request) {
        for (HydraMessage message : request.getMessages()) {
            return this.extractMessageBody(message);
        }
        return null;
    }

    /**
     * Extrai o conteudo de uma {@link HydraMessage}.
     * 
     * @param hydraMessage {@link HydraMessage}
     * @return conteudo da mensagem
     */
    private String extractMessageBody(HydraMessage hydraMessage) {
        String messageBody = null;

        if (hydraMessage != null) {
            BaseDAO<HydraMessageImpl> dao = this.hydraController.getDAOFactory().getGenericDAO(HydraMessageImpl.class);
            try {
                HydraMessageImpl hydraMessageImpl = dao.findByPk(hydraMessage.getId());
                messageBody = hydraMessageImpl.getBodyAsString();
            } catch (BeanNotFoundException e) {
                messageBody = "Erro interno! A mensagem (ID: " + hydraMessage.getId() + ") não foi encontrada!";
            } catch (IOException e) {
                messageBody = "Erro interno! Não foi possivel ler os dados da mensagem (ID: " + hydraMessage.getId() + ")!";
            }
        }

        return messageBody;
    }

    /**
     * @return {@link HydraRequestDAO}.
     */
    private HydraRequestDAO getHydraRequestDAO() {
        return this.hydraController.getDAOFactory().getDAOByClass(HydraRequestDAO.class);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected MessageCreator getHelpTextCreator() {
        return HelpTextMessages.CONSULTA_DETALHE_INTEGRACAO_REQUISICAO;
    }
}
